# -*- coding: utf-8 -*-
""" SGML parsing module. Not for production! """
__all__ = ['parse_sgml', 'swap_dict', 'find', 'xml_path', 'html_escape', 'html_unescape', 'findtag']
__author__ = 'Sergey Sobko, Timir Nureev'
__copyright__ = 'Copyright (c) 2010, DEKO PROFIT (The ProfitWare Project)'
__license__ = 'BSD'
__credits__ = ['Sergey Sobko', 'Timir Nureev']
__email__ = 'info@dekoprofit.ru'
__status__ = 'Development'

import re

html_escape_table = {"&":"&amp;",'"': "&quot;","'": "&apos;",">": "&gt;","<": "&lt;",}


__parse_sgml_pattern_tag, __parse_sgml_pattern_attr, __xml_path_pattern, __unescape_pattern, __parse_url_pattern = \
    map(re.compile, ['<(/)?([^\?].*?)( .*?)?(?: )?(/|)>(.*?)(?=(?:<|$))', '(?:(?: )+(\w+)="(.*?)")', '(?:/)(\w+)(?:\[(.+?)=(.+?)\])?', '&\w+;', '[\?|\&|=]'])

swap_dict = lambda x:dict([(v, k) for (k, v) in x.iteritems()])
find=re.findall
parse_sgml=lambda s,f=lambda t,n:t,n='':map(lambda d:f({d[1]:dict(find(__parse_sgml_pattern_attr,d[2])+[('__tagtype',len(d[3]+d[0]*2))]+[('__aftertext', d[4])])},n),find(__parse_sgml_pattern_tag,''.join(s.split('\n'))))
xml_path=lambda s:find(__xml_path_pattern,s) 
html_escape = lambda x: "".join(html_escape_table.get(c,c) for c in x)
html_unescape=lambda a: re.sub(__unescape_pattern, lambda x: swap_dict(html_escape_table)[x.group(0)], a)
html_strip=lambda a:re.sub(__parse_sgml_pattern_tag,lambda x:x.group(5),a)
parse_url=lambda u:dict((lambda t:zip(t[::2],t[1::2]))(['__page']+re.split(__parse_url_pattern,u)))

__tag, __pargs, __retargs = \
    map(re.compile, ['(\w+)?\[.*\]->(.*)$', '\[(\w+)(?:=(.*?))?\]', '(\w+)\((\w+)\)(?:,|$)'])
    
def findtag(mt, a):
    """ Like h1[style][__tagtype=0]->__aftertext(cp1251) """
    tag, ret = find(__tag, a)[0]
    retargs = find(__retargs, ret)
    found = mt.has_key(tag)
    if found:
        for id, value in find(__pargs, a):
            if not (mt[tag].has_key(id) and (value == '' or str(mt[tag][id]) == value)):
                found = False
                break
    if found:
        retlist = ()
        for key, enc in retargs:
            enc = enc == '' and 'utf-8' or enc
            if mt[tag].has_key(key):
                retlist += (mt[tag][key].decode(enc).encode('utf-8'),)
        return retlist[0]
    return None
